#ifndef __MY_HOT__
#define __MY_HOT__
#include "Util.hpp"
#include "Data.hpp"
#include <unistd.h>
#include "ThreadPool.hpp"
extern Cloud::DataManger *datamanger;

namespace Cloud
{
    class HotManger // 热点文件管理类
    {
    private:
        int hot_time;
        string pack_dir;
        string back_dir;
        static Cloud::ThreadPool *_threads;
        pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;

    public:
        HotManger()
        {
            _threads = new Cloud::ThreadPool(HotManger::packed);
            _threads->Start(); // 开启线程池
            hot_time = Cloud::Config::GetInstance()->GetHotTiem();
            pack_dir = Cloud::Config::GetInstance()->GetPackDir();
            back_dir = Cloud::Config::GetInstance()->GetBackDir();

            FileUtil tmp1(pack_dir);
            FileUtil tmp2(back_dir);
            if (!tmp1.CreateDirectory())
            {
                ERROR("%s", "CreateDirectory is fail");
                exit(-1);
            };
            if (!tmp2.CreateDirectory())
            {
                ERROR("%s", "CreateDirectory is fail");
                exit(-1);
            }
        }
        ~HotManger()
        {
            delete _threads;
        }
        bool HotJudge(const std::string &filename) // 判断当前文件是否为热点文件
        {
            FileUtil fu(filename);
            time_t latime = fu.LastATime();
            time_t cur_time = time(nullptr);
            // cout << cur_time << endl;
            // cout << latime << endl;
            // cout << hot_time << endl;
            if (cur_time - latime > hot_time)
            {
                return false;
            }
            return true;
        }

        static void packed(BackupInfo info, string realpath)
        {
            FileUtil tmp(realpath);
            info.packRunning = true;
            datamanger->Update(info); // 压缩前更新标志位，防止压缩过程中多次被多个线程压缩

            if (info.pack_flag == false)
            {
                bool ret = tmp.Compress(info.packpath);

                if (ret == false)
                {
                    info.packRunning = false;
                }
                else
                {
                    // 删除源文件
                    tmp.Remove();
                    info.pack_flag = true;
                    datamanger->Update(info);
                }
            }
        }

        bool RunModule()
        {
            while (1)
            {
                vector<string> array;
                FileUtil fu(back_dir);
                fu.ScanDirectory(&array); // 获取备份文件目录的所有文件
                for (int i = 0; i < array.size(); i++)
                {
                    if (HotJudge(array[i])) // 判断是否为热点数据
                        continue;

                    BackupInfo bi;
                    // 获取当前文件备份信息
                    // 如果当前数据在备份文件中不存在,则设置一个新的备份信息出来
                    if (datamanger->GetOneByRealpath(array[i], &bi) == false)
                    {
                        bi(array[i]);
                    }

                    pthread_mutex_lock(&_mutex);
                    // 对非热点数据进行压缩存储
                    if (bi.pack_flag == false && bi.packRunning == false)
                    {
                        bi.packRunning = true;
                        _threads->addTask(bi, bi.realpath);
                    }
                    pthread_mutex_unlock(&_mutex);
                }
                usleep(1000);
            }
            return true;
        }
    };
    ThreadPool *Cloud::HotManger::_threads = nullptr;
}
#endif
